package study.kit.el.zh.table;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Tuple;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.map.multi.RowKeyTable;
import cn.hutool.core.map.multi.Table;
import cn.hutool.core.util.ReflectUtil;
import com.google.common.base.Stopwatch;
import lombok.extern.slf4j.Slf4j;
import study.kit.el.zh.parse.CellVO;
import study.kit.el.zh.parse.RangeVO;
import study.kit.el.zh.parse.RowVO;

import java.util.List;
import java.util.Map;

/**
 * 解析数据
 */
@Slf4j
public class TableUtil {

    /**
     * 解析
     *
     * @param ctx
     * @return List<TableRow>
     */
    public static List<TableRow> parse(TableCtx ctx) {
        return parse(ctx.getHeader(),
                ctx.getRangeLt(),
                ctx.getDataLt(),
                ctx.getRowSize(),
                ctx.getColSize());
    }

    /**
     * 解析
     *
     * @param header
     * @param rangeLt
     * @param dataLt
     * @return List<TableRow>
     */
    public static List<TableRow> parse(RowVO header,
                                       List<RangeVO> rangeLt,
                                       List<RowVO> dataLt,
                                       int rowSize,
                                       int colSize) {
        // 头部
        Map<Integer, String> colNum2NameMap = CollectionUtil.toMap(header.getCellVOLt(), null,
                CellVO::getColNum,
                e -> Convert.toStr(e.getValue()));
        // 合并
        Table<Integer, Integer, Tuple> rangeTbl = RangeUtil.getMergeCoord(rangeLt);
        // 数据
        Table<Integer, Integer, Object> dataTbl = new RowKeyTable<>();
        dataLt.forEach(e -> {
            e.getCellVOLt().forEach(d -> {
                dataTbl.put(e.getRowNum(), d.getColNum(), d.getValue());
            });
        });

        // 双遍历
        Stopwatch stopwatch = Stopwatch.createStarted();
        List<TableRow> rowLt = ListUtil.toList();
        // 行（从 1 开始）
        for (int rowNum = 1; rowNum < rowSize; rowNum++) {
            //log.info("=====第 {} 行====", rowNum);
            //
            TableRow row = new TableRow();
            row.setRowNum(rowNum);

            // 列
            List temp = ListUtil.toList();
            for (int colNum = 0; colNum < colSize; colNum++) {
                // ****** 获取值  ******
                Object value;
                if (rangeTbl.contains(rowNum, colNum) && !dataTbl.contains(rowNum, colNum)) {
                    Tuple p = rangeTbl.get(rowNum, colNum);
                    value = dataTbl.get(p.get(0), p.get(1));
                } else {
                    value = dataTbl.get(rowNum, colNum);
                }
                temp.add(value);

                //TODO ****** 验证 ******
                String colName = MapUtil.getStr(colNum2NameMap, colNum);
                Validator.checkData(colName, value, rowNum, colNum);

                // ****** 设置属性 ******
                String fieldName = HeaderUtil.getFieldName(colName);
                ReflectUtil.setFieldValue(row, fieldName, value);
                //log.info("({}, {}): {}", rowNum, colNum, value);
            }
            log.info("{}", temp);

            rowLt.add(row);
        }
        //log.info("{}, {} cost time [{}] ms", rowSize, colSize, stopwatch.elapsed(TimeUnit.MILLISECONDS));
        return rowLt;
    }
}
